const_castconst_cast는 const 또는 volatile 특성을 추가하거나 제거한다.
volatile 키워드는 컴파일러에게 변수가 다른 곳에서 수정될 수 있음을 알린다.
(해당 메모리 항목은 캐싱하거나, 레지스터에 보관하지 않음)
const와 volatile 키워드 모두 암시적으로 추가될 수 있다.
휘발성이 있는 개체에 volatile 특성을 제거하면, 캐시와 레지스터에 있는 값이 일치하지 않을 수 있으며
정의되지 않은 동작을 할 수 있다.
비휘발성 개체를 참조할 때만, volatile로 한정된 포인터와 레퍼런스로 volatile 특성을 제거할 수 있다.
const 특성을 제거하면, 콜 스택 전체에서 연관된 모든 const 한정자를 무효화한다.
실수로 데이터를 덮어 쓸 경우, 디버깅 작업이 증가하게 됨
reinterpret_castreinterpret_cast는 가장 공격적인 형태를 갖는 형변환이다.
개체의 메모리 위치를 가져온 후, 개체의 비트를 마치 다른 타입인 것처럼 해석한다.
ex)
비트 체인으로 형변환해 부동소수점 수의 단일 비트로 변경할 수 있게 해준다.
함수 스타일 변환생성자를 사용해 값을 변환할 수 있다.
T 타입에 U 타입을 인수로 받는 생성자를 사용해, U 타입의 개체로부터 T 타입의 개체를 생성할 수 있다.
U u;
T t(u);
U u;
T t{u};
생성자 표기법을 사용해 값을 변환
struct dense_matrix{ };
struct compressed_matrix{ };
void f(const dense_matrix&){}
int main(void){
compressed_matrix A;
f(dense_matrix(A));
}
위에서 compressed_matrix 객체 A를 이용해서 dense_matrix를 생성한다.
아래 중 하나를 필요로 한다.
- compressed_matrix를 허용하는 dense_matrix 생성자
- compressed_matrix를 dense_matrix로 변환하는 변환 연산자
struct compressed_matrix;
struct dense_matrix{
dense_matrix()=default;
dense_matrix(const compressed_matrix& A){ }
};
struct compressed_matrix{
operator dense_matrix(){
dense_matrix A;
return A;
}
};
int main(void){
compressed_matrix A;
f(A);
}
둘다 구현 가능 하다면, 생성자로 구현하는 것이 좋다.
C++11 부터 명시적 변환 연산자를 제공한다.
하지만, 이는 내재적 타입에 대하여 C 스타일 형변환처럼 동작한다.
double d=3.0;
const double* const dp=&d;
long l=long(dp);
long l(dp);
위에 코드에서 const_cast 동작과 reinterpret_cast가 수행된다.
따라서 형변환시, static_cast와 같은 형변환 연산자를 사용하는 것이 좋다.
암시적 변환일반적으로 암시적 변환 규칙은 우선순위에 구속받지 않는다.
암시적 변환 요약
FROM |
TO |
T |
T의 슈퍼타입 |
T |
const T |
T |
volatile T |
T[N] |
T* |
T |
U |
함수 |
함수 포인터 |
nullptr_t |
T* |
정수 |
더 큰 정수 |
수치 타입 |
다른 수치 타입 |
생성자나 변한 연산자를 explicit으로 선언하지 않은 경우, 암시적으로 변한을 수행함